#include	"stdlib.h"
#include	"estools.h"
#include	"time.h"
#include	"stdio.h"
#include 	"stdlib.h"
#include 	"fcntl.h"
#include 	"stdio.h"
#include 	"sys/types.h"
#include 	"sys/stat.h"
#include 	"signal.h"
#include 	"sys/types.h"
#include 	"errno.h"
#include	"string.h"

#ifndef		COMMANDCHAR
#define		COMMANDCHAR ';'
#endif

#ifndef		SPLITCHAR
#define		SPLITCHAR '='
#endif

extern "C"
void TrimAll(char * pSource,char * pTarget)
{

	char *p=pSource;	
	char *q=pTarget;
	unsigned char ch;
	ch=(unsigned char)*p;
	long flag=1;	
	
	while(ch!=0)
	{
		if(((ch=='\t')||(ch<=0x20))&&(flag==1))	
		{
			p++;
			ch=(unsigned char)*p;
			continue;
		}
		flag=0;
		*q=(char)ch;
		p++;
		q++;
		ch=*p;
	}		
	*q=(char)ch;
	p=pTarget+strlen(pTarget)-1;
	q=pTarget;
	flag=1;
	while(p>=q)
	{
		ch=(unsigned char)*p;
		if(((ch=='\t')||(ch<=0x20))&&(flag==1))	
		{
			p--;
			continue;
		}
		flag=1;
		*(p+1)=0;
		break;
	}
}

extern "C"
void TrimLeft(char * pSource,char * pTarget)
{

	char *p=pSource;	
	char *q=pTarget;
	unsigned char ch;
	ch=(unsigned char)*p;
	long flag=1;	
	
	while(ch!=0)
	{
		if(((ch=='\t')||(ch<=0x20))&&(flag==1))	
		{
			p++;
			ch=(unsigned char)*p;
			continue;
		}
		flag=0;
		*q=(char)ch;
		p++;
		q++;
		ch=(unsigned char)*p;
	}		
	*q=(char)ch;
}

extern "C"
long ExtractKey(char * pSource, char * pKey, char * pValue)
{

	char * p=pSource;
	int nFlag=0;
	char ch,ch0;
	int KeyLen=strlen(pKey);
	int nStart=0;
	ch=*p;
	ch0=0;
	while(ch!=0)
	{
		switch(nFlag)
		{
			case 0:	//normal
				if((strncmp(p,pKey,KeyLen)==0)&&
					((ch0==0)||(ch0==0x20)||(ch0==';')||(ch0==0x09)))
				{
					nFlag=2;//wait for '='
					nStart+=KeyLen;
					p+=KeyLen;
				}
				else
				{
					if(ch=='\'')
						nFlag=1;//find '\''
					p++;
					nStart++;
					ch0=ch;
				}
				break;
			case 1://'\''
				if(ch=='\'')
					nFlag=0;//end '\''
				p++;
				nStart++;
				ch0=ch;
				break;
			case 2://wait for '='
				if(ch=='=')//find
				{
					strcpy(pValue,pSource+nStart+1);
					char * pTempValue=strdup(pValue);
					TrimAll(pTempValue,pValue);
					free(pTempValue);
					return 1;
				}
				if((ch!=' ')&&(ch!='\r')&&
					(ch!='\n')&&(ch!='\t')) // key error
				{
					nFlag=0;
				}
				p++;
				nStart++;
				ch0=ch;
				break;
		}	
		ch=*p;
	}
	*pValue=0;
	return 0;
}


extern "C"
void TrimRight(char * pSource,char * pTarget)
{

	char *p=pSource;	
	char *q=pTarget;
	unsigned char ch;
	ch=(unsigned char)*p;
	long flag=1;	
	strcpy(pTarget,pSource);	
	*q=(char)ch;
	p=pTarget+strlen(pTarget)-1;
	q=pTarget;
	flag=1;
	while(p>=q)
	{
		ch=(unsigned char)*p;
		if(((ch=='\t')||(ch==0x20))&&(flag==1))	
		{
			p--;
			continue;
		}
		flag=1;
		*(p+1)=0;
		break;
	}
}

extern "C"
long ExtractString(char * pSource, char chtok,char * pString)
{
    char *p=pSource;
    long StrLen=strlen(pSource);
    char ch;
    int nFlag=0;
    int index=0;
    ch=*p;
    while(ch!=0)
    {
        switch(nFlag)
        {
            case 0://normal;
                if(ch==chtok)
                {
                    strncpy(pString,pSource,index);
                    pString[index]=0;
                    return (index+1);
                }
                if(ch=='\'')
                {
                    nFlag=1;
                }
                if(ch=='\"')
                {
                    nFlag=2;
                }
                break;
            case 1://have '\''
                if(ch=='\'')
                {
                    nFlag=0;
                }
                break;
            case 2://have '\"'
                if(ch=='\"')
                {
                    nFlag=0;
                }
                break;
        }
        index++;
        p++;
        ch=*p;
    }
    //not found;
    strcpy(pString,pSource);
    return(strlen(pSource));
}

extern "C"
long ExtractCommand(char * pSource, char * pCommand)
{
	char *p=pSource;
	long StrLen=strlen(pSource);
	char ch;
	int nFlag=0;
	int index=0;
	ch=*p;
	while(ch!=0)
	{
		switch(nFlag)
		{
			case 0://normal;
				if(ch==COMMANDCHAR)
				{
					strncpy(pCommand,pSource,index);
					pCommand[index]=0;
					return (index+1);
				}
				if(ch=='\'')
				{
					nFlag=1;
				}
				if(ch=='\"')
				{
					nFlag=2;
				}
				break;
			case 1://have '\''
				if(ch=='\'')
				{
					nFlag=0;
				}
				break;
			case 2://have '\"'
				if(ch=='\"')
				{
					nFlag=0;
				}
				break;
		}
		index++;
		p++;
		ch=*p;
	}
	//not found;
	strcpy(pCommand,pSource);
	return(strlen(pSource));
}

extern "C"
void	ShowCurTime()
{
    time_t t0;
#ifndef	_WIN32
	tm localtm;
	tm * tm0=&localtm;
#else
    tm *tm0;
#endif
    t0=time(0);
#ifdef	_WIN32
    tm0=localtime(&t0);
#else
	localtime_r(&t0,&localtm);
#endif
    printf("Current Time : %02d:%02d:%02d \n",tm0->tm_hour,tm0->tm_min,
           tm0->tm_sec);

}

extern "C"
void    GetCurTime(char * pTime)
{
    time_t t0;
#ifndef _WIN32
    tm localtm;
    tm * tm0=&localtm;
#else
    tm *tm0;
#endif
    t0=time(0);
#ifdef  _WIN32
    tm0=localtime(&t0);
#else
    localtime_r(&t0,&localtm);
#endif
    sprintf(pTime,"%04d/%02d/%02d  %02d:%02d:%02d",tm0->tm_year+1900,
		tm0->tm_mon+1,tm0->tm_mday,tm0->tm_hour,tm0->tm_min,
           tm0->tm_sec);

}

extern "C"
void    GetNowDateStr(char * pTime)
{
    time_t t0;
#ifndef _WIN32
    tm localtm;
    tm * tm0=&localtm;
#else
    tm *tm0;
#endif
    t0=time(0);
#ifdef  _WIN32
    tm0=localtime(&t0);
#else
    localtime_r(&t0,&localtm);
#endif
    sprintf(pTime,"%04d%02d%02d%02d%02d%02d",tm0->tm_year+1900,
		tm0->tm_mon+1,tm0->tm_mday,tm0->tm_hour,tm0->tm_min,
           tm0->tm_sec);

}

extern "C"
void    GetNowTimeStr(char * pTime)
{
    time_t t0;
#ifndef _WIN32
    tm localtm;
    tm * tm0=&localtm;
#else
    tm *tm0;
#endif
    t0=time(0);
#ifdef  _WIN32
    tm0=localtime(&t0);
#else
    localtime_r(&t0,&localtm);
#endif
    sprintf(pTime,"%02d%02d%02d",tm0->tm_hour,tm0->tm_min,
           tm0->tm_sec);

}

extern "C"
void    GetCurDateStr(char * pTime)
{
    time_t t0;
#ifndef _WIN32
    tm localtm;
    tm * tm0=&localtm;
#else
    tm *tm0;
#endif
    t0=time(0);
#ifdef  _WIN32
    tm0=localtime(&t0);
#else
    localtime_r(&t0,&localtm);
#endif
    sprintf(pTime,"%04d%02d%02d",tm0->tm_year+1900,
		tm0->tm_mon+1,tm0->tm_mday);

}

extern "C"
void    GetYesterdayDateStr(char * pTime)
{
    time_t t0;
#ifndef _WIN32
    tm localtm;
    tm * tm0=&localtm;
#else
    tm *tm0;
#endif
    t0=time(0);
	t0-=24*3600;
#ifdef  _WIN32
    tm0=localtime(&t0);
#else
    localtime_r(&t0,&localtm);
#endif
    sprintf(pTime,"%04d%02d%02d",tm0->tm_year+1900,
		tm0->tm_mon+1,tm0->tm_mday);

}


extern "C"
void    GetCurDate(long * nYear,long * nMon,long *nDay)
{
    time_t t0;
#ifndef _WIN32
    tm localtm;
    tm * tm0=&localtm;
#else
    tm *tm0;
#endif
    t0=time(0);
#ifdef  _WIN32
    tm0=localtime(&t0);
#else
    localtime_r(&t0,&localtm);
#endif
	*nYear=tm0->tm_year+1900;
    *nMon=tm0->tm_mon+1;
	*nDay=tm0->tm_mday;

}

extern "C"
long SplitKey(char * pSource, char * pKey, char * pValue)
{
    char *p=pSource;
    long StrLen=strlen(pSource);
    char ch;
    int nFlag=0;
    int index=0;
    ch=*p;
    while(ch!=0)
    {
        switch(nFlag)
        {
            case 0://normal;
                if(ch==SPLITCHAR)
                {
                    strncpy(pKey,pSource,index);
                    pKey[index]=0;
					strcpy(pValue,pSource+index+1);
                    return (index+1);
                }
                if(ch=='\'')
                {
                    nFlag=1;
                }
                if(ch=='\"')
                {
                    nFlag=2;
                }
                break;
            case 1://have '\''
                if(ch=='\'')
                {
                    nFlag=0;
                }
                break;
            case 2://have '\"'
                if(ch=='\"')
                {
                    nFlag=0;
                }
                break;
        }
        index++;
        p++;
        ch=*p;
    }
    //not found;
	pKey[0]=0;
	pValue[0]=0;
    return(0);
}

#define		MAXSTRLEN	0x10000

extern "C"
char ** CreateStrList(char * pSource,char ch)
{
	if(pSource==0)
		return NULL;
	if((*pSource)==0)
		return NULL;
	long nCount=0;
	char *pString;
	char *pStart=pSource;
	do
	{
		pString=strchr(pStart,ch);
		if(pString==0)
		{
			nCount++;	
			break;
		}
		nCount++;
		pStart=pString+1;
        if(pStart[0]==0)
            break;
	}
	while(pString!=0);
	if(nCount<=0)
	{
		return NULL;
	}
	char **pList=(char **)malloc((nCount+1)*sizeof(char *));
	pList[nCount]=0;
    
	char pBuffer[MAXSTRLEN];
    pBuffer[0]=0;
    pStart=pSource;
    long nStart=0;
    long nCopy;
	long i=0;
    do
    {
        pString=strchr(pStart,ch);
        if(pString==0)
        {
            if(strlen(pStart)<MAXSTRLEN)
            {
				strcpy(pBuffer,pStart);
            }
            pStart=0;
        }
        else
        {
            nCopy=strlen(pStart)-strlen(pString);
            if(nCopy<MAXSTRLEN)
            {
                strncpy(pBuffer,pStart,nCopy);
            	pBuffer[nCopy]=0;
            }
            else
            {
               	strncpy(pBuffer,pStart,MAXSTRLEN-1); 
            	pBuffer[MAXSTRLEN-1]=0;
            }
            pStart=pString+1;
        }
		pList[i]=strdup(pBuffer);
		TrimAll(pBuffer,pList[i]);
		i++;
    }
    while((pStart!=0)&&(*pStart!=0)&&(i<nCount));
	return pList;
}

extern "C"
void    DeleteStrList(char **pStrList)
{
	char *p;
	char **pPtr=pStrList;
	if(pStrList==0)
	{
		return;
	}
	do
	{
		p=*pPtr;
		if(p)
		{
			free(p);
			*pPtr=0;
		}
		pPtr++;
	}
	while(*pPtr!=0);
	free(pStrList);
}


extern "C"
long    GetStrListCount(char **pStrList)
{
    char **pPtr=pStrList;
    if(pStrList==0)
    {
        return 0;
    }
	char *p;
	long nCount=0;
    while(*pPtr!=0)
	{
        p=*pPtr;
        if(p)
        {
			nCount++;
        }
        pPtr++;
    }
	return nCount;
}

extern "C" void
ChopStr(char * pSource,char chChop)
{
	char * p=pSource+strlen(pSource)-1;
	while(p>=pSource)
	{
		if((*p)!=chChop)
		{
			break;
		}
		else
		{
			*p=0;
			p--;
		}
	}		
}



static unsigned char get_char_from_index(unsigned index)
{
	if(index<26)
		return('a'+index);
	if(index<52)
		return('A'+index-26);
	if(index<62)
		return ('0'+index-52);
	if(index==62)
		return '!';
	else
		return '$';
}

static unsigned char get_index_from_char(unsigned ch)
{
    if((ch>='a')&&(ch<='z'))
        return(ch-'a');
    if((ch>='A')&&(ch<='Z'))
        return(ch-'A'+26);
    if((ch>='0')&&(ch<='9'))
        return(ch-'0'+52);
	if(ch=='!')
		return 62;
    return (63);
}

extern "C"
long	EncodeKey(unsigned char * pKeyCode,unsigned char * pKeyData)
{
	unsigned long nlen=strlen((char *)pKeyCode);
	if(nlen>=20)
		return 0;
	if(nlen<0)
		return 0;
	unsigned char pNewData[32];
	memset(pNewData,0,32);
    unsigned char * p;
    unsigned char * q;
    unsigned char ch;
    if(nlen<=0)
    {
//      printf("not enough length !\n");
        return 0;
    }
    p=pKeyCode;
    unsigned long i;
    unsigned long j=0;
    unsigned long sum=0;
    unsigned char xornum=time(0)%64;
    unsigned char xorch=get_char_from_index(xornum);
    q=pNewData;
    *q=xorch;
    q++;
    p=pKeyCode;
    i=0;
    while(i<nlen)
    {
        sum=0;
        if(i>=nlen)
        {
            ch=(0x20)^xornum;
        }
        else
        {
            ch=(*p)^xornum;
            p++;
            i++;
        }
        sum=sum*256+ch;
                if(i>=nlen)
        {
            ch=(0x20)^xornum;
        }
        else
        {
            ch=(*p)^xornum;
            p++;
            i++;
        }
        sum=sum*256+ch;
        if(i>=nlen)
        {
            ch=(0x20)^xornum;
        }
        else
        {
            ch=(*p)^xornum;
            p++;
            i++;
        }
        sum=(unsigned char )sum*256+ch;
        ch=(unsigned char )sum%64;
        *q=get_char_from_index(ch);
        q++;
        sum=sum/64;
        ch=(unsigned char )sum%64;
        *q=get_char_from_index(ch);
        q++;
        sum=sum/64;

        ch=(unsigned char )sum%64;
        *q=get_char_from_index(ch);
        q++;
        sum=sum/64;

        ch=(unsigned char )sum%64;
        *q=get_char_from_index(ch);
        q++;
    }
	TrimAll((char *)pNewData,(char *)pKeyData);
	return 1;
}

extern "C"
long	DecodeKey(unsigned char * pKeyData,unsigned char * pKeyCode)
{
    unsigned char *p=pKeyData;
	unsigned char pNewData[32];
	memset(pNewData,0,32);
    unsigned char *q=pNewData;
    unsigned nlen=(unsigned long)strlen((char *)pKeyData);
    if((nlen%4)!=1)
    {
        return 0;
    }
    unsigned long i=0;
    p=pKeyData;
    unsigned char ch=*p;
    unsigned char xornum=get_index_from_char(*p);
	unsigned long sum=0;
    while(i<nlen-1)
    {
        sum=0;
        p=pKeyData+i+4;
        ch=get_index_from_char(*p);
        sum=sum*64+ch;
        p--;
        i++;
        ch=get_index_from_char(*p);
        sum=sum*64+ch;
        p--;
        i++;

        ch=get_index_from_char(*p);
        sum=sum*64+ch;
        p--;
        i++;

        ch=get_index_from_char(*p);
        sum=sum*64+ch;
        p--;
        i++;
        q+=2;
        ch=(unsigned char )sum%256;
        *q=ch^xornum;
        q--;
        sum=sum/256;
        ch=(unsigned char )sum%256;
        *q=ch^xornum;
        q--;
        sum=sum/256;
        ch=(unsigned char )sum%256;
        *q=ch^xornum;
        q+=3;
    }
	TrimAll((char *)pNewData,(char *)pKeyCode);
	return 1;
}


///////////////////////////////////////////////////////////
extern "C" char* SGetCurTime(char* pszTime, char* pszFmt)
{
    time_t ltime;
    struct tm *today;
    time( &ltime );
    today = localtime( &ltime );

    if(NULL == pszFmt)
        sprintf(pszTime, "%04d-%02d-%02d %02d:%02d:%02d", 1900+today->tm_year,today->tm_mon+1,today->tm_mday,today->tm_hour,today->tm_min,today->tm_sec);
    else
        sprintf(pszTime, pszFmt, 1900+today->tm_year,today->tm_mon+1,today->tm_mday,today->tm_hour,today->tm_min,today->tm_sec);
    return pszTime;
}

extern "C" char* SGetCurTailTime(char* pszTime, char* pszFmt)
{
    time_t ltime;
    struct tm *today;
    time( &ltime );
    today = localtime( &ltime );

    if(NULL == pszFmt)
        sprintf(pszTime, "%02d:%02d:%02d", today->tm_hour,today->tm_min,today->tm_sec);
    else
        sprintf(pszTime, pszFmt, today->tm_hour,today->tm_min,today->tm_sec);
    return pszTime;
}

extern "C" char *getstimeval(char *buf)
{
        timeval_t tv;
        struct tm      tm;
        size_t         len = 28;

        gettimeofday(&tv, NULL);
        localtime_r(&tv.tv_sec, &tm);
        strftime(buf, len, "%Y-%m-%d %H:%M:%S", &tm);
        len = strlen(buf);
        sprintf(buf + len, ".%06.6d", (int)(tv.tv_usec));

        return buf;
}


extern "C" char* SGetCurDate(char* pszDate, char* pszFmt)
{
    time_t ltime;
    struct tm *today;
    time( &ltime );
    today = localtime( &ltime );

    if(NULL == pszFmt)
        sprintf(pszDate, "%04d-%02d-%02d", 1900+today->tm_year,today->tm_mon+1,today->tm_mday);
    else
        sprintf(pszDate, pszFmt/*"%04d-%02d-%02d"*/, 1900+today->tm_year,today->tm_mon+1,today->tm_mday);
    return pszDate;
}

extern "C" double difftimeval(const timeval_t *tv1, const timeval_t *tv2)
{
        double d;
        time_t s;
        suseconds_t u;

        s = tv1->tv_sec - tv2->tv_sec;
        u = tv1->tv_usec - tv2->tv_usec;
        if (u < 0)
                --s;

        d = s;
        d *= 1000000.0;
        d += u;

        return d;
}

extern "C" char *strftimeval(const timeval_t *tv, char *buf)
{
        struct tm      tm;
        size_t         len = 28;

        localtime_r(&tv->tv_sec, &tm);
        strftime(buf, len, "%Y-%m-%d %H:%M:%S", &tm);
        len = strlen(buf);
        sprintf(buf + len, ".%06.6d", (int)(tv->tv_usec));
        return buf;
}



